package com.cicdi.util;


import com.platon.contracts.ppos.NodeContract;
import com.platon.contracts.ppos.ProposalContract;
import com.platon.contracts.ppos.StakingContract;
import com.platon.contracts.ppos.dto.CallResponse;
import com.platon.contracts.ppos.dto.resp.Node;
import com.platon.contracts.ppos.dto.resp.Proposal;
import com.platon.contracts.ppos.dto.resp.TallyResult;
import com.platon.protocol.Web3j;
import com.platon.protocol.core.DefaultBlockParameterName;
import com.platon.protocol.core.methods.response.PlatonBlock;
import com.platon.protocol.http.HttpService;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author haypo
 * @date 2021/3/3
 */
public class Web3jUtil {
    public static final Web3j web3j = Web3j.build(new HttpService(Common.DEFAULT_NODE_URL));
    static StakingContract sc = StakingContract.load(web3j);
    static NodeContract nc = NodeContract.load(web3j);
    static ProposalContract pc = ProposalContract.load(web3j);

    public static ObservableList<Node> getNodeList() {
        try {
            List<Node> nodes = nc.getCandidateList().send().getData();
            return FXCollections.observableList(nodes);
        } catch (Exception e) {
            e.printStackTrace();
            return FXCollections.emptyObservableList();
        }
    }

    public static ObservableList<Proposal> getProposalList() {
        try {
            List<Proposal> proposals = pc.getProposalList().send().getData();
            return FXCollections.observableList(proposals);
        } catch (Exception e) {
            e.printStackTrace();
            return FXCollections.emptyObservableList();
        }
    }

    public static String getPackageReward() {
        try {
            BigInteger bigInteger = sc.getPackageReward().send().getData();
            return ConvertUtil.von2Hrp(bigInteger).toPlainString();
        } catch (Exception e) {
            e.printStackTrace();
            return "0";
        }
    }

    public static String getAvgPackageTime() {
        CallResponse<BigInteger> response = null;
        try {
            response = sc.getAvgPackTime().send();
            return response.getData().toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "0";
        }
    }

    public static String getBlockByHash(String hash) {
        PlatonBlock block;
        try {
            block = web3j.platonGetBlockByHash(hash, true).send();
            return JsonUtil.toPrettyJsonString(block.getBlock());
        } catch (Exception ioException) {
            ioException.printStackTrace();
            return "暂无查询结果";
        }
    }

    public static List<TallyResult> getTallyResults() {
        return getProposalList().stream().map(s -> {
            try {
                return pc.getTallyResult(s.getProposalId()).send().getData();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }).collect(Collectors.toList());
    }

    public static TallyResult getTallyResult(String pid) throws Exception {
        return pc.getTallyResult(pid).send().getData();
    }

    public static BigInteger getBlockNumber() throws IOException {
        PlatonBlock.Block block;
        block = web3j.platonGetBlockByNumber(DefaultBlockParameterName.LATEST, false).send().getBlock();
        return block.getNumber();
    }

}
